package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.CaseLeaveFlag;
import cn.fintecher.pangolin.entity.elastic.BaseCase;
import cn.fintecher.pangolin.entity.elastic.LeaveCaseModel;
import cn.fintecher.pangolin.entity.mysql.CaseInfo;
import cn.fintecher.pangolin.entity.mysql.QCaseInfo;
import cn.fintecher.pangolin.service.dataimp.elastic.BaseCaseElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.LeaveCaseModelElastic;
import cn.fintecher.pangolin.service.dataimp.model.ConfirmCommonModel;
import cn.fintecher.pangolin.service.dataimp.model.ConfirmModel;
import cn.fintecher.pangolin.service.dataimp.repository.CaseInfoRepository;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.apache.commons.collections4.IterableUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 15:14 2019/11/5
 */

@Service("confirmLeaveFuture")
public class ConfirmLeaveFuture {
    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private BaseCaseElastic baseCaseElastic;

    @Autowired
    private LeaveCaseModelElastic leaveCaseModelElastic;

    /**
     * 多线程确认
     */
    @Async
    public CompletableFuture<ConfirmModel> processLeave(List<LeaveCaseModel> list) {
        ConfirmModel model = new ConfirmModel();
        List<CaseInfo> caseInfos = new ArrayList<>();
        List<BaseCase> baseCases = new ArrayList<>();
        List<String> caseNumbers = new ArrayList<>();
        List<LeaveCaseModel> models = new ArrayList<>();
        for (LeaveCaseModel leaveCaseModel : list) {
            caseNumbers.add(leaveCaseModel.getCaseNumber());
        }
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.termsQuery("caseNumber.keyword", caseNumbers));
        Iterable<CaseInfo> caseInfoIterable = caseInfoRepository.findAll(QCaseInfo.caseInfo.caseNumber.in(caseNumbers));
        Iterable<BaseCase> baseCaseIterable = baseCaseElastic.search(builder);
        List<CaseInfo> caseInfoList = IterableUtils.toList(caseInfoIterable);
        List<BaseCase> baseCaseList = IterableUtils.toList(baseCaseIterable);
        Map<String, ConfirmCommonModel> map = new HashMap<>();
        for (LeaveCaseModel leaveCaseModel : list) {
            ConfirmCommonModel confirmCommonModel = new ConfirmCommonModel();
            confirmCommonModel.setLeaveCaseModel(leaveCaseModel);
            for (CaseInfo caseInfo : caseInfoList) {
                if (leaveCaseModel.getCaseNumber().equals(caseInfo.getCaseNumber())) {
                    confirmCommonModel.setCaseInfo(caseInfo);
                    break;
                }
            }
            for (BaseCase baseCase : baseCaseList) {
                if (leaveCaseModel.getCaseNumber().equals(baseCase.getCaseNumber())) {
                    confirmCommonModel.setBaseCase(baseCase);
                    break;
                }
            }
            map.put(leaveCaseModel.getCaseNumber(), confirmCommonModel);
        }
        for (Map.Entry<String, ConfirmCommonModel> entry : map.entrySet()) {
            ConfirmCommonModel confirmCommonModel = entry.getValue();
            LeaveCaseModel leaveCaseModel = confirmCommonModel.getLeaveCaseModel();
            BaseCase baseCase = confirmCommonModel.getBaseCase();
            CaseInfo caseInfo = confirmCommonModel.getCaseInfo();
            leaveCaseModel.setOriginalDate(baseCase.getEndCaseDate()); //原退案时间
            models.add(leaveCaseModel);
            if (Objects.nonNull(caseInfo)) {
                caseInfo.setLeaveFlag(CaseLeaveFlag.HAS_LEAVE); //留案标识
                caseInfo.setLeaveExpireDate(leaveCaseModel.getDate()); //留案到期时间
                caseInfo.setEndCaseDate(leaveCaseModel.getDate()); //退案时间
                caseInfos.add(caseInfo);
            }
            baseCase.setEndCaseDate(leaveCaseModel.getDate()); //退案时间
            baseCases.add(baseCase);
        }
        RepositoryUtil.saveData(leaveCaseModelElastic, models);
        model.setCaseInfos(caseInfos);
        model.setBaseCases(baseCases);
        return CompletableFuture.completedFuture(model);
    }
}
